package com.landtool.lanbase.shipping;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.protobuf.InvalidProtocolBufferException;
import com.landtool.lanbase.config.SysConfig;
import com.landtool.lanbase.constant.CacheConsts;
import com.landtool.lanbase.elasticsearch.ElasticServer;
import com.landtool.lanbase.entity.ShipEntity;
import com.landtool.lanbase.proto.Protocol;
import com.landtool.lanbase.utils.YmlConfigurerUtil;
import com.landtool.lanbase.utils.ZlibUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zeromq.ZMQ;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 获取船只数据方法
 */
@Component
public class GetShipData {

    private static Logger log = LoggerFactory.getLogger(GetShipData.class);

    @Autowired
    private FormatProcess formatProcess;

    @Autowired
    private ShippingService shippingService;

    @Autowired
    private ElasticServer elasticServer;

    @Autowired
    private PushService pushService;

    @Autowired
    private SysConfig sysConfig;

    private static int count = 0;

    /**
     * 获取rest结果
     * @return
     */
    public String getRestTypeData() {
        //获取到的字符串保存到result里面
        String result = "";
        String restType = "rest";
        if (restType.equals(CacheConsts.openType)) {
            if (CacheConsts.isLogin) {
                String loginKey = "sys." + restType + "_" + CacheConsts.openProvince + "_login";
                //获取数据的地址key
                String datakey = "sys." + restType + "_" + CacheConsts.openProvince + "_url";
                result = getRequestString(YmlConfigurerUtil.getStrYmlVal(loginKey), YmlConfigurerUtil.getStrYmlVal(datakey));

            } else {
                //拼接无需登录的key
                String datakey = "sys." + restType + "_" + CacheConsts.openProvince + "_url";
                result = HttpUtil.get(YmlConfigurerUtil.getStrYmlVal(datakey), 3000);
            }
        }
        if (!"".equals(result)) {
            log.info("-----数据已接受-----");
        }
        return result;
    }


    /**
     * 获取cookie
     *
     * @param loginUrl 登陆地址
     */
    public void getCookie(String loginUrl) {
        try {
            HttpResponse res = HttpRequest.post(loginUrl).execute();
            JSONObject json = JSONUtil.parseObj(res.body());
            Integer code = json.getInt("code");
            //用户登陆成功
            if (code == 0) {
                CacheConsts.cookie = res.headers().get("Set-Cookie").get(0);
                if (!CacheConsts.cookie.contains("JSESSIONID") && res.headers().get("Set-Cookie").size() == 2) {
                    CacheConsts.cookie = res.headers().get("Set-Cookie").get(1);
                }
            }
            if (code == -1) {
                log.info("用户已被登陆");
                CacheConsts.cookie = "";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据
     *
     * @param loginUrl 登录地址
     * @param datakey  获取列表地址
     */
    public String getRequestString(String loginUrl, String datakey) {
        String result = "";
        //该用户已登录
        if ("".equals(CacheConsts.cookie)) {
            getCookie(loginUrl);
        } else {
            try {
                HttpResponse res = HttpRequest.post(datakey).cookie(CacheConsts.cookie).timeout(10 * 1000).execute();
                result = res.body();
                //如果cookie不能使用，.body会返回空
                if (result.equals("")) {
                    //退出登录 302
                    loginOut(loginUrl);
                    CacheConsts.cookie = "";
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("HttpRequest 请求出错：" + e.getMessage());
            }
        }
        return result;
    }

    /**
     * 退出登录
     *
     * @param loginUrl 登录地址
     */
    public void loginOut(String loginUrl) {
        loginUrl = loginUrl.split("\\?")[0];
        loginUrl = loginUrl.replace("login", "logout");
        HttpRequest.post(loginUrl).cookie(CacheConsts.cookie).execute();
    }


    /**
     * 获取zmq数据
     */
    public void getZmqTypeData() {
        while (true) {
            try {
                String datakey = "sys." + CacheConsts.openType + "_" + CacheConsts.openProvince + "_url";
                ZmqTypeData(YmlConfigurerUtil.getStrYmlVal(datakey));
            } catch (Exception e) {
                e.printStackTrace();
                log.error("socket有问题" + e.toString());
            }
        }
    }


    /**
     * 获取zmq的数据
     *
     * @param url
     * @return
     */
    public void ZmqTypeData(String url) {
        List <ShipEntity> list = new ArrayList <>();
        ZMQ.Socket socket = null;
        ZMQ.Context context = ZMQ.context(1);
        try {
            socket = context.socket(ZMQ.SUB);
            socket.connect(url);
            socket.setReceiveTimeOut(10 * 1000);
            String filter = "Targets";
            socket.subscribe(filter.getBytes());
            while (true) {
                String msg = "";
                byte[] recv = {};
                try {
                    msg = socket.recvStr(0).trim();
                    recv = socket.recv(0);
                    log.info("recv的长度为" + recv.length);
                    Protocol.Targets t = null;
                    try {
                        t = Protocol.Targets.parseFrom(ZlibUtils.decompress(recv));
                        assert t != null;
                        formatProcess.getZmqNewArray(t);
                        //船只数据对比，分析，修改
                        HashMap <String, List <ShipEntity>> map = shippingService.analyzeShipping();
                        //数据推送
                        pushService.pushShipData(map);
                        //es保存
                        if (count == sysConfig.getPushNum()) {
                            elasticServer.bulkShipDates();
                            pushService.pushAllShipData();
                            elasticServer.tagetChangesSave();
                            count = 0;
                        } else {
                            count++;
                        }

                    } catch (InvalidProtocolBufferException e) {
                        e.printStackTrace();
                        log.error("解压数据错误");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("接受数据为空或者超时" + e.toString());
                    throw e;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("socket有问题" + e.toString());
            throw e;

        } finally {
            socket.disconnect(url);
            socket.close();
            context.term();
        }
    }


}
